package belf.migrate.api.table.schema;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 该类表示MySQL、Oracle等数据库的扩展索引信息
 */
public class IndexKeyExt {
    private List<ColumnWithSequence> columns;
    /** 从源表获取的索引名称，可用于目标表创建索引 */
    private String indexName;
    /** 是否创建唯一索引 */
    private boolean unique;
    /** 索引是升序还是降序，可选值为ASC、DESC */
    private String indexOrder;
    /** 每种数据库个性化的索引类型名称 */
    private String indexTypeName;

    public IndexKeyExt() {
        columns = new ArrayList<>();
    }

    public IndexKeyExt(List<ColumnWithSequence> columns,
                         String indexName,
                         boolean unique,
                         String indexOrder,
                         String indexTypeName) {
        this.columns = columns;
        this.indexName = indexName;
        this.unique = unique;
        this.indexOrder = indexOrder;
        this.indexTypeName = indexTypeName;
    }

    public List<ColumnWithSequence> getColumns() {
        return columns;
    }

    public void addColumnWithSequence(ColumnWithSequence columnWithSequence) {
        columns.add(columnWithSequence);
    }

    public String getIndexName() {
        return indexName;
    }

    public void setIndexName(String indexName) {
        this.indexName = indexName;
    }

    public boolean isUnique() {
        return unique;
    }

    public void setUnique(boolean unique) {
        this.unique = unique;
    }

    public String getIndexOrder() {
        return indexOrder;
    }

    public void setIndexOrder(String indexOrder) {
        this.indexOrder = indexOrder;
    }

    public String getIndexTypeName() {
        return indexTypeName;
    }

    public void setIndexTypeName(String indexTypeName) {
        this.indexTypeName = indexTypeName;
    }

    public List<String> getSortedColumnNames() {
        Collections.sort(columns);
        return columns.stream().map(columnWithSequence -> columnWithSequence.getColumnName()).collect(Collectors.toList());
    }

    @Override
    public String toString() {
        return "MySQLIndexKey{" +
                "columns=" + columns +
                ", indexName='" + indexName + '\'' +
                ", unique=" + unique +
                ", indexOrder='" + indexOrder + '\'' +
                ", indexTypeName='" + indexTypeName + '\'' +
                '}';
    }

    /** 被索引字段，及其在联合索引（如果有）中的序号。对于联合索引，字段序号很重要，会影响查询效率 */
    public static class ColumnWithSequence implements Comparable<ColumnWithSequence>{
        /** 被索引的字段 */
        private String columnName;
        /** 对于联合索引 */
        private int sequenceInIndex;

        public ColumnWithSequence(String columnName, int sequenceInIndex) {
            this.columnName = columnName;
            this.sequenceInIndex = sequenceInIndex;
        }

        public String getColumnName() {
            return columnName;
        }

        public int getSequenceInIndex() {
            return sequenceInIndex;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            ColumnWithSequence that = (ColumnWithSequence) o;
            return sequenceInIndex == that.sequenceInIndex && columnName.equals(that.getColumnName());
        }

        @Override
        public int hashCode() {
            return Objects.hash(columnName, sequenceInIndex);
        }

        @Override
        public String toString() {
            return "ColumnWithSequence{" +
                    "columnName='" + columnName + '\'' +
                    ", sequenceInIndex=" + sequenceInIndex +
                    '}';
        }

        @Override
        public int compareTo(ColumnWithSequence o) {
            return this.sequenceInIndex - o.getSequenceInIndex();
        }
    }
}
